home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / RSX.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  10KB  |  440 lines

  1. /*****************************************************************************
  2.  * FILE: rsx.c                                     *
  3.  *                                         *
  4.  * DESC:                                     *
  5.  *    - get rsx options                             *
  6.  *    - switch protected mode (16bit)                      *
  7.  *    - init protected mode                             *
  8.  *    - check copro, install emu                         *
  9.  *    - load first a.out prg                             *
  10.  *                                         *
  11.  * Copyright (C) 1993,1994                             *
  12.  *    Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld             *
  13.  *    email: rainer@mathematik.uni-bielefeld.de                 *
  14.  *                                         *
  15.  *****************************************************************************/
  16.  
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include "DPMI.H"
  21. #include "PRINTF.H"
  22. #include "PROCESS.H"
  23. #include "START32.H"
  24. #include "LOADPRG.H"
  25. #include "FPU.H"
  26. #include "RSX.H"
  27. #include "DOSERRNO.H"
  28. #include "RMLIB.H"
  29. #include "COPY32.H"
  30. #include "SYSDEP.H"
  31. #include "DJIO.H"
  32. #include "VERSION.H"
  33.  
  34. /* command-line options */
  35. char copro = 1;         /* prg need 387 : 0=no 1=yes 3=emulate */
  36. char opt_memaccess = 0;     /* allows memaccess */
  37. char opt_stack = 0;        /* stack: expand down or data segment */
  38. char rsx387_in_dosmem = 1;    /* rsx387 in dos memory (not rsx32) */
  39. char opt_force_dpmi09 = 1;    /* force only DPMI 0.9 calls */
  40. char opt_version = 0;        /* print rsx version */
  41. char opt_force_copro;        /* force copro status */
  42. int  opt_stackval = 0;        /* stack size in KB */
  43. int  opt_max_dos_handles;    /* DOS handles for RSX */
  44. char opt_nocore;        /* don't write core file */
  45. char opt_schedule;        /* enable schedule() */
  46. int  opt_memalloc = 0;        /* pre-alloc heap */
  47. char opt_zero = 0;        /* zero heap */
  48. char opt_os2 = 0;        /* set os/2 bit */
  49.  
  50. /* special test options */
  51. char opt_kdeb;            /* Kernel debug mode */
  52. char opt_printall = 0;        /* show all information (testing RSX) */
  53. char opt_print_syscalls = 0;    /* show every sys_call (testing RSX) */
  54. char opt_redir;         /* redirect handle 1 (testing RSX) */
  55. char opt_debugrsx;        /* debug rsx; don't set int3 */
  56.  
  57. /* other globals */
  58. char npx_present;        /* npx present 1/0 */
  59. char kdeb_program[80];        /* program for kernel debug mode */
  60.  
  61. int rsx_stdout = 1;
  62. int kread;            /* keyboard read */
  63. int kready;            /* keyboard check */
  64. unsigned bios_selector;     /* selector bios area */
  65.  
  66. char **org_env;         /* org. environment to rsx */
  67. int org_envc;            /* org. env items */
  68.  
  69. static int emxl_psp = 0;    /* exe-stub emxl.exe psp */
  70.  
  71. int hexstr2int(char *s)
  72. {
  73.     int i, res=0;
  74.  
  75.     for (i = 0; i < 4; i++) {
  76.     char c = s[i];
  77.     if (c >= 'a')
  78.         c -= ('a' - 10);
  79.     else if (c >= 'A')
  80.         c -= ('A' - 10);
  81.     else
  82.         c -= '0';
  83.     res <<= 4;
  84.     res |= c;
  85.     }
  86.     return res;
  87. }
  88.  
  89. /* return first non-digit */
  90. static char * asc2int(char *s, int *retv)
  91. {
  92.     char *str = s;
  93.     *retv = 0;
  94.  
  95.     while (*str != 0) {
  96.     if ((*str < '0') || (*str > '9'))
  97.         break;
  98.     *retv *= 10;
  99.     *retv += *str - '0';
  100.     str++;
  101.     }
  102.     return (str);
  103. }
  104.  
  105. /*
  106. ** get one options for rsx
  107. ** return last char pos, if successful
  108. */
  109. char *scan_for_option(char *s, NEWPROCESS *p)
  110. {
  111.     int temp;
  112.     char *t;
  113.  
  114.     switch (*s) {
  115.  
  116.     /*
  117.     **    emx options with emxbind:
  118.     **    -a*, -c, -f#, -h#, -p, -s#, -C#, -L
  119.     */
  120.  
  121.     case 'a':                   /* DOS features */
  122.     for (++s; *s > ' '; ++s) {
  123.         if (*s == 'm') {
  124.         if (p)
  125.             p->options |= OPT_MEMACCESS;
  126.         else
  127.             opt_memaccess = 1;
  128.         }
  129.         else if (*s == 'c' || *s == 'i' || *s == 'w')
  130.         continue;
  131.         else
  132.         return NULL;
  133.     }
  134.     if (*(--s) == 'a')
  135.         return NULL;
  136.     break;
  137.  
  138.     case 'c':                   /* core */
  139.     opt_nocore = 1;
  140.     break;
  141.  
  142.     case 'e':   /* changed !! */
  143.     puts("-e option for copro has changed to -Re");
  144.     return NULL;
  145.  
  146.     case 'f':                   /* frame size (ignore) */
  147.     case 's':                   /* stack size (ignore) */
  148.     case 'C':                   /* commit */
  149.     while (isdigit(*++s))
  150.         ;
  151.     --s;
  152.     break;
  153.  
  154.     case 'h':                   /* max handles */
  155.     ++s;
  156.     if (!isdigit(*s))
  157.         return NULL;
  158.     t = asc2int(s, &temp);
  159.     if (p && temp > opt_max_dos_handles)
  160.         rm_sethandles(temp);
  161.     opt_max_dos_handles = temp;
  162.     return t;
  163.  
  164.     case 'p':                   /* don't use lower DOS mem */
  165.     rsx387_in_dosmem = 0;
  166.     break;
  167.  
  168.     case 'R':       /* special RSX options */
  169.     for (++s; *s > ' '; ++s) {
  170.         if (*s == ',')
  171.         ++s;
  172.         switch (*s) {
  173.         case 'a':                   /* ss = ds */
  174.             opt_stack = 1;
  175.             break;
  176.         case 'e':                   /* copro */
  177.             copro = 0;
  178.             if (isdigit(*(s+1)))
  179.             opt_force_copro = *(++s) - '0' + 1;
  180.             break;
  181.         case 'm':                   /* malloc for memaccess */
  182.             if (!isdigit(*(s+1)))
  183.             break;
  184.             s = asc2int(++s, &opt_memalloc) - 1;
  185.             break;
  186.         case 's':                   /* stack frame */
  187.             ++s;
  188.             if (!isdigit(*s))
  189.             return NULL;
  190.             return asc2int(s, &opt_stackval);
  191.         case 'x':                   /* enable schedule */
  192.             opt_schedule = 1;
  193.             break;
  194.         case 'z':                   /* zero heap */
  195.             opt_zero = 1;
  196.             break;
  197.  
  198.         case '1':                   /* no dpmi10 calls */
  199.             opt_force_dpmi09 = 0;
  200.             break;
  201.         case '9':                   /* no dpmi10 calls */
  202.             opt_force_dpmi09 = 1;
  203.             break;
  204.  
  205.         case 'D':                   /* don't touch int3 */
  206.             opt_debugrsx = 1;
  207.             break;
  208.         case 'F':                   /* redirect output */
  209.             opt_redir = 1;
  210.             break;
  211.         case 'I':                   /* print syscalls */
  212.             opt_print_syscalls = 1;
  213.             break;
  214.         case 'K':                   /* kernel debug */
  215.             opt_kdeb = 1;
  216.             break;
  217.         case 'O':                   /* set OS/2 bit */
  218.             opt_os2 = 1;
  219.             break;
  220.         case 'P':                   /* print syscalls */
  221.             opt_printall = 1;
  222.             break;
  223.         default:
  224.             puts("unknown -Rxx option");
  225.             return NULL;
  226.         }
  227.     }
  228.     if (*(--s) == 'R')
  229.         return NULL;
  230.     break;
  231.  
  232.     case 'V':                   /* version print */
  233.     opt_version = 1;
  234.     break;
  235.  
  236.     default:
  237.     return NULL;
  238.  
  239.     } /* switch (*s) */
  240.  
  241.     return s;
  242. }
  243.  
  244. static void init_bios_keyboard(void)
  245. {
  246.     /* get DPMI selector for BIOS area, on error try 0x40 */
  247.     if (SegToSel(0x40, &bios_selector))
  248.     bios_selector = 0x40;
  249.  
  250.     /* services for enhanced keyboards, otherwise older types */
  251.     if ((BYTE) read32(bios_selector, 0x96) & 0x10) {
  252.     kread = 0x10;
  253.     kready = 0x11;
  254.     } else {
  255.     kread = 0;
  256.     kready = 1;
  257.     }
  258.  
  259.     /* flush input */
  260.     while (rm_bios_read_keybrd(kready))
  261.     rm_bios_read_keybrd(kread);
  262. }
  263.  
  264. static int setup_environment(char **env)
  265. {
  266.     char *s;
  267.  
  268.     /* save environment, env-size */
  269.     for (org_envc = 0; env[org_envc] != NULL; org_envc++)
  270.     ;
  271.     org_env = env;
  272.  
  273.     /* get enviroment options */
  274.     s = getenv("RSXOPT");
  275.     if (s != NULL) {
  276.     for (; *s != '\0'; ++s) {
  277.         while (*s == ' ')
  278.         ++s;
  279.         if (*s == '-') {
  280.         s = scan_for_option(++s, NULL);
  281.         if (s == NULL) {
  282.             puts(version);
  283.             puts("error in RSXOPT");
  284.             return (1);
  285.         }
  286.         } else
  287.         break;
  288.     }
  289.     }
  290.     return 0;
  291. }
  292.  
  293. static int get_rsx_options(int start, char **argv)
  294. {
  295.     int i;
  296.     char *s;
  297.  
  298.     for (i = start; argv[i]; i++) {
  299.     if (argv[i][0] == '-') {
  300.         s = scan_for_option(& argv[i][1], NULL);
  301.         if (s == NULL) {
  302.         puts(version);
  303.         printf("bad option: %s\n", argv[i]);
  304.         return -1;
  305.         }
  306.     } else
  307.         break;
  308.     }
  309.     return i;
  310. }
  311.  
  312. #ifdef __EMX__
  313. #define exit(x) dos_exit(x)
  314. #endif
  315.  
  316. /*
  317. ** MAIN():
  318. ** real mode for rsx16
  319. ** protected mode rsx32
  320. */
  321.  
  322. void main(int argc, char **argv, char **env)
  323. {
  324.     static char exefile[128];
  325.     int file_arg, err;
  326.  
  327. #ifndef __EMX__
  328.     set_stdout();
  329. #endif
  330.     init_real_mode();
  331.  
  332.     if (setup_environment(environ))
  333.     exit(1);
  334.  
  335.     /* check bound exe-file */
  336.     if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '/'
  337.     && argv[1][6] == '/') {
  338.     emxl_psp = hexstr2int(&argv[1][2]);
  339.     get_emxl_psp(emxl_psp);
  340.     build_emx_args(&argc, &argv);
  341.     file_arg = 0;
  342.     } else if (argc > 1 && strcmp(argv[1], "!proxy") == 0) {
  343.     build_dj_args(&argc, &argv);
  344.     emxl_psp = 1;
  345.     file_arg = 0;
  346.     } else if (strcmp(argv[0], "!RSX") == 0) {
  347.     emxl_psp = 1;
  348.     file_arg = 1;
  349.     } else {
  350.     file_arg = get_rsx_options(1, argv);
  351.     if (file_arg == -1)
  352.         exit(1);
  353.     opt_version = 1;
  354.     }
  355.  
  356.     /* print version, if rsx running from prompt */
  357.     if (opt_version)
  358.     puts(version);
  359.  
  360.     /* check filename */
  361.     if (argc <= file_arg) {
  362.     puts("no filename defined");
  363.     exit(1);
  364.     }
  365.  
  366.     /* copro required, 387 there ? */
  367.     npx_present = (char) npx_installed();
  368.  
  369.     if (opt_force_copro)
  370.     copro = opt_force_copro - (char) 1;
  371.     else if (copro == 1 && !npx_present)
  372.     copro = 3;
  373.  
  374.     if (real_to_protected(1))
  375.     exit(1);
  376.  
  377.     /* - - - now protected mode! - - - rsx/rsx32 */
  378.  
  379.     if (test_dpmi_capabilities())
  380.     protected_to_real(1);
  381.  
  382.     if (hangin_extender()) {
  383.     puts("ERROR: can't hang in extensions");
  384.     protected_to_real(1);
  385.     }
  386.  
  387.     if (opt_kdeb && argv[file_arg + 2])
  388.     strcpy(kdeb_program, argv[file_arg + 2]);
  389.  
  390.     /* init process-tables */
  391.     init_this_process();
  392.  
  393.     /* init bios_selector & get keyboard */
  394.     init_bios_keyboard();
  395.  
  396.     strcpy(exefile, argv[file_arg]);
  397.     if (rm_access(exefile, 0) == -1) {
  398.     strcat(exefile, ".exe");
  399.     if (rm_access(exefile, 0) == -1) {
  400.         printf("file not found: %s\n", argv[file_arg]);
  401.         shut_down(1);
  402.     }
  403.     }
  404.     if (!opt_max_dos_handles)
  405.     opt_max_dos_handles = N_FILES;
  406.     else if (opt_max_dos_handles > RSX_NFILES)
  407.     opt_max_dos_handles = RSX_NFILES;
  408.     rm_sethandles(opt_max_dos_handles);
  409.  
  410.     /* hang in emulation */
  411.     if (copro == 3)
  412.     if (install_rsx387())
  413.         shut_down(2);
  414.  
  415.     init_fpu();
  416.  
  417.     /* rsx output */
  418.     if (opt_redir)
  419.     if ((rsx_stdout = rm_creat("rsx.log", _A_NORMAL)) < 0)
  420.         rsx_stdout = 1;
  421.  
  422.     err = exec32(P_WAIT, exefile, argc - file_arg, argv + file_arg, org_envc, org_env);
  423.  
  424.     printf("%s: ", exefile);
  425.     switch (err) {
  426.     case EMX_ENOEXEC:
  427.         puts("Not a valid a.out format");
  428.         break;
  429.     case EMX_ENOMEM:
  430.         puts("Not enough DPMI memory");
  431.         break;
  432.     default:
  433.         printf("Can't load file, emx errno = %d\n", err);
  434.         break;
  435.     }
  436.  
  437.     shut_down(1);
  438.     /* never reached */
  439. }
  440.